//
// Created by u on 23-7-25.
//

#ifndef CLOUD_CHINT_SRC_TASK_HPP_
#define CLOUD_CHINT_SRC_TASK_HPP_

#include <iostream>
#include <vector>
#include <string>
#include <functional>
#include <chrono>
#include <thread>
#include <mutex>

using namespace std;
using namespace chrono;
using namespace chrono_literals;

using TaskFuncCallback = std::function<void()>;
/* 定时任务结构体 */
struct timedTaskStruct {
	std::string name;
	std::chrono::microseconds timeInterval; // 时间片
	std::chrono::microseconds endTime;
	TaskFuncCallback parseFunc;

	timedTaskStruct(const std::string&& name,
		const std::chrono::microseconds& time,
		const std::chrono::microseconds& end_time,
		const TaskFuncCallback& parseFunc)
		: name(name), timeInterval(time), endTime(end_time), parseFunc(parseFunc) {
	}

};

class TaskManager {

public:
	/* 添加固定时间任务结构体 */
	bool addTask(const timedTaskStruct& taskStruct) {
		std::lock_guard<std::mutex> _lck(timedTaskListMutex_);
		timedTaskList_.push_back(taskStruct);
		return true;
	}
	/* 删除指定名称任务结构体 */
	bool delTaskByName(const std::string& name) {
		std::lock_guard<std::mutex> _lck(timedTaskListMutex_);
		for (auto it = timedTaskList_.begin(); it != timedTaskList_.end(); it++) {
			if (it->name == name) {
				timedTaskList_.erase(it);
				return true;
			}
		}
		return false;
	}
	/* 初始化idle线程 */
	void init() {
		timedTaskStruct task{
			"idle",
			duration_cast<microseconds>(1s),
			duration_cast<microseconds>(system_clock::now().time_since_epoch()),
			[]{
			  while (true) {
				  std::this_thread::sleep_for(1s);
			  }
			}
		};
		// 初始化，添加调用函数接口
		addTask(std::move(task));
	}
	/* 任务调度器，循环执行即可 */
	void schedule() {
		auto current_time = duration_cast<microseconds>(system_clock::now().time_since_epoch());
		for (auto& th : timedTaskList_) {
			if (current_time > th.endTime) {
				if (th.parseFunc)
					th.parseFunc();
				th.endTime = current_time + th.timeInterval;
			}
		}
		std::this_thread::sleep_for(1ms);
	}

private:
	std::vector<timedTaskStruct> timedTaskList_;
	std::mutex timedTaskListMutex_;
};

#endif //CLOUD_CHINT_SRC_TASK_HPP_
